#include "xen/audio/audio_master.hpp"

#include "platform/openal/openal_audio_source.hpp"
#include "platform/openal/openal_audio_buffer.hpp"
#include "platform/openal/openal_listener.hpp"

#include "platform/sdl_mixer/listener.hpp"

namespace Xen {

AudioAPI::API AudioMaster::api_ = AudioAPI::API::None;
Ref<AudioListener> AudioMaster::listener_ = nullptr;

void AudioMaster::Init(AudioAPI::API api) {
    api_ = api;
    switch (api_) {
#ifdef ENABLE_OPENAL
        case AudioAPI::OpenAL:
            AudioCommand::Init();
            listener_ = std::make_shared<OpenALAudioListener>();
            break;
#endif
#ifdef ENABLE_SDL2_MIXER
        case AudioAPI::SDL2_Mixer:
            AudioCommand::Init();
            listener_ = std::make_shared<SDLMixerListener>();
            break;
#endif
        default:
            XEN_CORE_ASSERT(false, "Unknown audio API type");
    }
}

void AudioMaster::Shutdown() {
    AudioCommand::Shutdown();
}

Ref<AudioBuffer> AudioMaster::CreateAudioBuffer(const std::string& filepath) {
    return AudioBuffer::Create(filepath);
}

Ref<AudioSource> AudioMaster::CreateAudioSource() {
    return AudioSource::Create();
}

Ref<AudioBuffer> AudioLibrary::Load(const std::string name, const std::string& filepath) {
    if (audios_.find(name) == audios_.end()) {
        audios_[name] = AudioBuffer::Create(filepath);
    }
    return audios_[name];
}

Ref<AudioBuffer> AudioLibrary::Get(const std::string name) {
    auto it = audios_.find(name);
    if (it != audios_.end()) {
        return it->second;
    }
    return nullptr;
}

void AudioLibrary::Add(const std::string name, const Ref<AudioBuffer>& buffer) {
    if (audios_.find(name) == audios_.end()) {
        audios_[name] = buffer;
    }
}

}
